package com.lovely3x.versionchecklibrary;

import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
import android.widget.TextView;

import com.lovely3x.common.CommonApplication;
import com.lovely3x.common.versioncontroller.ApplicationUtils;
import com.lovely3x.common.versioncontroller.Version;
import com.lovely3x.common.versioncontroller.impls.ClickNotificationToInstallActivity;
import com.lovely3x.jobservice.JobService;
import com.lovely3x.jobservice.JobServiceManager;
import com.lovely3x.jobservice.executors.extensions.downloader2.DownloadTask;
import com.lovely3x.jobservice.executors.extensions.downloader2.exception.CancelException;
import com.lovely3x.jobservice.executors.extensions.downloader2.executor.DownloadProgress;
import com.lovely3x.jobservice.executors.extensions.downloader2.executor.DownloadTaskExecutor;
import com.lovely3x.jobservice.executors.extensions.downloader2.utils.DownloadUtils;
import com.lovely3x.jobservice.task.Progress;
import com.lovely3x.jobservice.task.Task;

import java.io.File;
import java.util.HashMap;
import java.util.Random;

import butterknife.ButterKnife;

/**
 * 发现新版本的提示对话框
 * Created by lovely3x on 16-2-18.
 */
public class FoundNewVersionDialog extends DialogFragment implements View.OnClickListener {

    public static final String EXTRA_VERSION = "extra.version.obj";
    public static final String EXTRA_TASK_WHAT = "extra.task.what";
    public static final String EXTRA_TASK_FILE = "extra.task.file";

    private static final int DOWNLOAD_NOTIFY_ID = 3421;
    private static final int RETRY_REQUEST_CODE = 10209399;
    private static final int CANCEL_REQUEST_CODE = 102343;

    private Version remoteVersion;

    private long mNewVersionDownloadWhat = 4323102345748523L;

    private Button mBtnNegative;
    private Button mBtnPositive;

    private TextView mTvMessage;
    private TextView mTvTitle;

    private ProgressBar mPbProgress;
    private File mDownloadFile;
    private JobServiceManager.SimpleJobServiceListener mSJSL;

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        remoteVersion = getArguments().getParcelable(EXTRA_VERSION);
        if (savedInstanceState != null) {
            if (remoteVersion == null)
                remoteVersion = savedInstanceState.getParcelable(EXTRA_VERSION);
        }

        mDownloadFile = getStoreFile(getContext());

        if (remoteVersion == null)
            throw new IllegalArgumentException("Remote version can't be null. ");

        final NotificationManager nm = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
        nm.cancel(DOWNLOAD_NOTIFY_ID);

        JobServiceManager.getInstance().registerJobServiceListener(this.mSJSL = new JobServiceManager.SimpleJobServiceListener() {
            @Override
            public void onTaskResumed(Task task, Exception e) {
                onTaskExecuted(task, e, null);
            }

            @Override
            public void onTaskExecuted(Task task, Exception e, Progress progress) {
                if (task.getWhat() == mNewVersionDownloadWhat) {
                    if (e == null) {
                        if (task instanceof DownloadTask) {
                            String path = ((DownloadTask) task).getStorePath();
                            Context context = getActivity() == null ? CommonApplication.getInstance() : getActivity();
                            Version archiveVersion = ApplicationUtils.getArchivePackageVersion(context, path);
                            //下载的版本和目标版本相同
                            File file = new File(path);
                            if (file.exists() && archiveVersion != null && archiveVersion.getVersionCode() == remoteVersion.getVersionCode()) {
                                //下载成功
                                JobServiceManager.getInstance().unregisterJobServiceListener(this);
                                //如果对话框还在显示，说明是前台更新
                                //将 ‘确认’ 按钮变化为 ’安装‘
                                if (getDialog() != null && getDialog().isShowing()) {
                                    mBtnPositive.setText(R.string.install);
                                    mBtnPositive.setVisibility(View.VISIBLE);
                                    mPbProgress.setMax(1);
                                    mPbProgress.setProgress(1);
                                    mPbProgress.setVisibility(View.VISIBLE);
                                    //下载成功
                                    mTvMessage.setText(R.string.download_successful);
                                    //切换文字为 ‘取消’ 样式
                                    mBtnNegative.setText(R.string.cancel);

                                } else {
                                    //如果在后台，那么就更改通知栏样式
                                    //后台发送通知展示
                                    Intent intent = ClickNotificationToInstallActivity.makeLaunchIntent(getActivity(), mDownloadFile);
                                    intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
                                    PendingIntent pi = PendingIntent.getActivity(context, new Random().nextInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
                                    Notification notification = new NotificationCompat.Builder(context)
                                            .setSmallIcon(R.mipmap.ic_launcher_small)
                                            .setContentTitle(context.getString(R.string.app_name))
                                            .setContentText(context.getString(R.string.downloaded_click_to_install))
                                            .setContentIntent(pi)
                                            .setAutoCancel(false)
                                            .setProgress(1, 1, false).build();
                                    nm.notify(DOWNLOAD_NOTIFY_ID, notification);
                                }
                            } else {
                                JobServiceManager.getInstance().removeTask(mNewVersionDownloadWhat);
                            }
                        }

                    } else {//下载失败
                        if (getDialog() != null && getDialog().isShowing()) {
                            //在前台，展示为重试
                            mBtnPositive.setText(R.string.retry);
                            mBtnPositive.setVisibility(View.VISIBLE);
                            mTvMessage.setText(R.string.download_new_version_failure);
                        } else {
                            //在后台，更改通知栏样式为重试样式
                            if (e instanceof CancelException) {
                                //用户主动取消，取消掉通知栏
                                nm.cancel(DOWNLOAD_NOTIFY_ID);
                            } else {
                                //retry
                                Context context = getActivity() == null ? CommonApplication.getInstance() : getActivity();
                                RemoteViews retryView = new RemoteViews(context.getPackageName(), R.layout.notify_retry);

                                //重试意图
                                Intent intent = new Intent(context, JobService.class);
                                intent.putExtra(JobService.EXTRA_ACTION, JobService.ACTION_RESUME_TASK);
                                intent.putExtra(JobService.EXTRA_TASK_WHAT, mNewVersionDownloadWhat);
                                PendingIntent retryIntent = PendingIntent.getService(context, RETRY_REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);

                                Intent cancelIntent = new Intent(context, JobService.class);
                                cancelIntent.putExtra(JobService.EXTRA_ACTION, JobService.ACTION_STOP_SERVICE);

                                PendingIntent cancelPendingIntent = PendingIntent.getService(context, CANCEL_REQUEST_CODE, cancelIntent, PendingIntent.FLAG_CANCEL_CURRENT);

                                //通知
                                Notification notification = new NotificationCompat.Builder(context)
                                        .setAutoCancel(true)
                                        .setSmallIcon(R.mipmap.ic_launcher_small)
                                        .setContent(retryView)
                                        .setContentTitle(String.format("%sV%s%s", context.getString(R.string.app_name),
                                                remoteVersion.getVersionName(), context.getString(R.string.downloading)))
                                        .setDeleteIntent(cancelPendingIntent)
                                        .setContentIntent(retryIntent)
                                        .build();
                                nm.notify(DOWNLOAD_NOTIFY_ID, notification);
                            }
                        }
                    }
                }
            }

            @Override
            public void onProgress(HashMap<Task, Progress> progresses) {
                if (mPbProgress != null) {
                    for (Task task : progresses.keySet()) {
                        if (task.getWhat() == mNewVersionDownloadWhat) {
                            DownloadProgress dp = (DownloadProgress) progresses.get(task);
                            switch (dp.getState()) {
                                case Progress.State.FAILURE:
                                    onTaskExecuted(task, new RuntimeException(), dp);
                                    break;
                                case Progress.State.SUCCESSFUL:
                                    onTaskExecuted(task, null, dp);
                                    break;
                                default: {
                                    //前台展示
                                    if (getDialog() != null && getDialog().isShowing()) {
                                        mPbProgress.setMax((int) dp.getMax());
                                        mPbProgress.setProgress((int) dp.getCurrent());
                                        mTvMessage.setText(R.string.downloading_please_wait_a_mount);
                                        mBtnPositive.setVisibility(View.GONE);
                                        mPbProgress.setVisibility(View.VISIBLE);
                                    } else {
                                        //后台发送通知展示
                                        Context context = getActivity() == null ? CommonApplication.getInstance() : getActivity();
                                        Notification notification = new NotificationCompat.Builder(context)
                                                .setSmallIcon(R.mipmap.ic_launcher_small)
                                                .setAutoCancel(true)
                                                .setContentTitle(context.getString(R.string.app_name))
                                                .setContentText(String.format("%sV%s%s", context.getString(R.string.app_name),
                                                        remoteVersion.getVersionName(), context.getString(R.string.downloading)))
                                                .setProgress((int) dp.getMax(), (int) dp.getCurrent(), false).build();
                                        nm.notify(DOWNLOAD_NOTIFY_ID, notification);
                                        //JobServiceManager.getInstance().startForeground(DOWNLOAD_NOTIFY_ID, notification);
                                    }
                                    break;
                                }
                            }

                            break;
                        }
                    }
                }
            }
        });

        View view = LayoutInflater.from(getContext()).inflate(R.layout.dialog_new_version_dialog, null);
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext()).setView(view);
        builder.setCancelable(!remoteVersion.isForceUpdate());
        setCancelable(!remoteVersion.isForceUpdate());

        AlertDialog dialog = builder.create();

        this.mBtnNegative = ButterKnife.findById(view, R.id.btn_dialog_new_version_negative);
        this.mBtnPositive = ButterKnife.findById(view, R.id.btn_dialog_new_version_positive);
        this.mTvTitle = ButterKnife.findById(view, R.id.tv_dialog_new_version_title);
        this.mTvMessage = ButterKnife.findById(view, R.id.tv_dialog_new_version_message);
        this.mPbProgress = ButterKnife.findById(view, R.id.pb_dialog_new_version_progress);

        this.mBtnNegative.setOnClickListener(this);
        this.mBtnPositive.setOnClickListener(this);

        mTvMessage.setText(remoteVersion.getDescription());
        mTvTitle.setText(String.format("%s V%s", getString(R.string.found_new_version), remoteVersion.getVersionName()));

        mBtnNegative.setVisibility(remoteVersion.isForceUpdate() ? View.GONE : View.VISIBLE);

        JobServiceManager.getInstance().autoPublish(true);
        return dialog;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        JobServiceManager.getInstance().publishOnceProgress();
        if (mDownloadFile.exists()) {
            Version archiveVersion = ApplicationUtils.getArchivePackageVersion(getActivity(), mDownloadFile.getAbsolutePath());
            if (archiveVersion != null && archiveVersion.getVersionCode() == remoteVersion.getVersionCode()) {

            }
        }

    }

    /**
     * 下载
     */
    public void download() {
        //JobServiceManager.getInstance().removeTask(mNewVersionDownloadWhat);
        JobServiceManager.getInstance().addTask(new DownloadTask(remoteVersion.getUrl(),
                mDownloadFile.getAbsolutePath(),
                DownloadUtils.REQUEST_METHOD_GET, DownloadTaskExecutor.SINGLE_DOWNLOAD_THREAD,
                mNewVersionDownloadWhat, DownloadTaskExecutor.EXECUTOR_TYPE));

        //Update tip content.
        mPbProgress.setProgress(0);
        mPbProgress.setMax(1);
        mTvMessage.setText(R.string.downloading_please_wait_a_mount);
        mBtnPositive.setVisibility(View.GONE);
        mPbProgress.setVisibility(View.VISIBLE);
    }


    /**
     * 获取下载文件保存对象
     * 将需要下载的文件保存在什么位置
     *
     * @return 保存的文件对象
     */
    protected File getStoreFile(Context context) {
        return ApplicationUtils.getNewVersionDownloadFile(context, remoteVersion);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(EXTRA_VERSION, remoteVersion);
        outState.putSerializable(EXTRA_TASK_WHAT, EXTRA_TASK_FILE);
    }

    @Override
    public void onDismiss(DialogInterface dialog) {
        super.onDismiss(dialog);
        FragmentActivity activity = getActivity();
        if (activity != null) activity.finish();
        VersionChecker.getInstance().onUpdateDialogDismiss(remoteVersion);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.btn_dialog_new_version_negative) {
            String btnText = mBtnNegative.getText().toString();
            if (getString(R.string.foreground).equals(btnText)) {//后台
                dismiss();
            } else if (getString(R.string.cancel).equals(btnText)) {//取消
                new AlertDialog.Builder(getActivity())
                        .setTitle(R.string.alert)
                        .setMessage(R.string.do_you_want_to_cancel_update)
                        .setNegativeButton(R.string.cancel, null)
                        .setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                JobServiceManager.getInstance().removeTask(mNewVersionDownloadWhat);
                                dialog.dismiss();
                                FoundNewVersionDialog.this.dismiss();
                            }
                        }).show();
            }

        } else if (id == R.id.btn_dialog_new_version_positive) {
            String btnText = mBtnPositive.getText().toString();
            if (getString(R.string.install).equals(btnText)) {//安装
                install();
            } else if (getString(R.string.download).equals(btnText)) {//下载
                download();
            } else if (getString(R.string.retry).equals(btnText)) {//重试
                JobServiceManager.getInstance().resumeTask(mNewVersionDownloadWhat);
            }

        }
    }

    /**
     * 安装
     */
    private void install() {
        Context context = getActivity() == null ? CommonApplication.getInstance() : getActivity();
        ClickNotificationToInstallActivity.launchMe(context, mDownloadFile);
    }
}
